/*
 * Copyright 2018-present KunMinX
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.nsgf.library.ui.page;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.NotificationManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Color;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.core.app.ActivityCompat;
import androidx.lifecycle.ViewModel;

import com.kunminx.architecture.ui.scope.ViewModelScope;
import com.nsgf.library.R;
import com.nsgf.library.base.BaseApplication;
import com.nsgf.library.base.DataBindingNsgfActivity;
import com.nsgf.library.data.response.manager.NetworkStateManager;
import com.nsgf.library.utils.AdaptScreenUtils;
import com.nsgf.library.utils.BarUtils;
import com.nsgf.library.utils.DialogController;
import com.nsgf.library.utils.ScreenUtils;
import com.nsgf.skjz.utils.CustomToast;
import com.nsgf.skjz.utils.SPUtil;
import com.nsgf.skjz.utils.SpKey;
import com.nsgf.skjz.utils.ToastUtils;
import com.nsgf.skjz.utils.Utils;

import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.List;

import javax.net.ssl.SSLHandshakeException;

import retrofit2.HttpException;

/**
 * Create by GC at 24/9/21
 */
public abstract class BaseActivity extends DataBindingNsgfActivity implements View.OnClickListener
        , LocationListener {

    private final ViewModelScope mViewModelScope = new ViewModelScope();


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {

        BarUtils.setStatusBarColor(this, Color.TRANSPARENT);
        BarUtils.setStatusBarLightMode(this, true);
        super.onCreate(savedInstanceState);

        getLifecycle().addObserver(NetworkStateManager.getInstance());

        bindViews();
    }

    protected <T extends ViewModel> T getActivityScopeViewModel(@NonNull Class<T> modelClass) {
        return mViewModelScope.getActivityScopeViewModel(this, modelClass);
    }

    protected <T extends ViewModel> T getApplicationScopeViewModel(@NonNull Class<T> modelClass) {
        return mViewModelScope.getApplicationScopeViewModel(modelClass);
    }

    @Override
    public Resources getResources() {
        if (ScreenUtils.isPortrait()) {
            return AdaptScreenUtils.adaptWidth(super.getResources(), 375);
        } else {
            return AdaptScreenUtils.adaptHeight(super.getResources(), 720);
        }
    }

    protected void toggleSoftInput() {
        InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
        imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
    }

    protected void openUrlInBrowser(String url) {
        Uri uri = Uri.parse(url);
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        startActivity(intent);
    }


    /**
     * 绑定默认的标准TitleBar  如果使用自定义的TitleBar只需要避免使用下面的id就OK
     */
    protected void bindViews() {
        backBtn = (ImageView) findViewById(R.id.title_bar_back);
        menuBtn = (ImageView) findViewById(R.id.title_bar_menu);
        titleTv = (TextView) findViewById(R.id.title_bar_root);

        title_bar_right = (ImageView) findViewById(R.id.title_bar_clear);


        if (backBtn != null)
            backBtn.setOnClickListener(this);
        if (menuBtn != null)
            menuBtn.setOnClickListener(this);
        if (title_bar_right != null)
            title_bar_right.setOnClickListener(this);

//        if (titleTv != null && backBtn != null)
//            backBtn.setColorFilter(titleTv.getCurrentTextColor());
    }


    /**
     * @param v
     * @deprecated not security method.Use {@link BaseActivity#onClickSecurity(View)}
     */
    @Override
    public void onClick(View v) {
        try {
            onClickSecurity(v);
        } catch (Exception e) {
            e.getMessage();
        }
    }

    /**
     * 返回按钮
     */
    protected ImageView backBtn;
    /**
     * 右上角的功能按钮
     */
    protected ImageView menuBtn;
    /**
     * 标题栏
     */
    protected TextView titleTv;


    protected ImageView title_bar_right;

    /**
     * 防止点击事件出错导致程序崩溃,提供了相对安全的事件响应容器
     *
     * @param v
     */
    protected void onClickSecurity(View v) {
        if (backBtn != null && backBtn.getId() == v.getId()) {
            onBackPressed();
        } else if (menuBtn != null && menuBtn.getId() == v.getId()) {
            onMenuClicked();
        }
    }

    protected void onMenuClicked() {

    }

    protected void onTitleClicked() {

    }


    public static final String MESSAGE_RECEIVED_ACTION = "com.nsgf.library.MESSAGE_RECEIVED_ACTION";
    public static final String MESSAGE_RECEIVED_DIALOG_CONTROLLER_ACTION = "com.nsgf.library.DIALOG_CONTROLLER_ACTION";
    public static final String MESSAGE_RECEIVED_ACTION_BOTTOM = "com.nsgf.library.MESSAGE_RECEIVED_ACTION_BOTTOM";
    public static final String MESSAGE_RECEIVED_ACTION_BOTTOM_NUMBER = "com.nsgf.library.MESSAGE_RECEIVED_ACTION_BOTTOM_NUMBER";

    DialogController dialogController;

    /**
     * 缺省的网络请求的流程框架 可以自定义
     *
     * @return BaseController
     */
    public DialogController getController() {
        if (dialogController == null) {
            dialogController = new DialogController(this);
        }
        return dialogController;
    }

    public void startLocation() {
        startLocation(false);
    }

    /**
     * 发起定位
     *
     * @param realTime 是否实时定位
     */
    public void startLocation(boolean realTime) {
        if (null == locationManager) {
            locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        }
        
        // 检查权限
        if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 0x123);
            return;
        }
        
        // 检查定位提供者是否可用
        boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        boolean networkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        
        if (!gpsEnabled && !networkEnabled) {
            ToastUtils.showLongToast("请打开定位服务");
            if (realTime) {
                showMissingPermissionDialog();
            }
            return;
        }
        
        try {
            // 优先使用GPS，如果GPS不可用则使用网络定位
            if (gpsEnabled) {
                if (realTime) {
                    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 0, this);
                } else {
                    locationManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, this, null);
                }
            } else if (networkEnabled) {
                if (realTime) {
                    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 5000, 0, this);
                } else {
                    locationManager.requestSingleUpdate(LocationManager.NETWORK_PROVIDER, this, null);
                }
            }
        } catch (SecurityException e) {
            Log.e("LocationError", "定位权限异常: " + e.getMessage());
            ToastUtils.showLongToast("定位权限异常，请检查权限设置");
        } catch (Exception e) {
            Log.e("LocationError", "定位异常: " + e.getMessage());
            ToastUtils.showLongToast("定位失败，请稍后重试");
        }
    }


    /**
     * 显示提示信息
     *
     * @since 2.5.0
     */
    private void showMissingPermissionDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(R.string.notifyTitle);
        builder.setMessage(R.string.notifyMsg);

        // 拒绝, 退出应用
        builder.setNegativeButton(R.string.cancel,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        finish();
                    }
                });

        builder.setPositiveButton(R.string.setting,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        startAppSettings();
                    }
                });

        builder.setCancelable(false);

        builder.show();
    }

    /**
     * 启动应用的设置
     *
     * @since 2.5.0
     */
    public void startAppSettings() {
        Intent intent = new Intent(
                Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.setData(Uri.parse("package:" + getPackageName()));
        startActivity(intent);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        getController().dismissLoading();
        if (null != locationManager)
            locationManager.removeUpdates(this);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (requestCode == 0x123) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // 用户授予了权限，重新尝试定位
                startLocation(false);
            } else {
                // 用户拒绝了权限，提示用户
                Toast.makeText(this, "需要定位权限才能获取位置信息", Toast.LENGTH_LONG).show();
            }
        }
    }


    public LocationManager locationManager;

    @Override
    public void onLocationChanged(@NonNull Location location) {
        if (location == null) {
            Log.e("LocationError", "接收到空的位置信息");
            return;
        }
        
        // 当位置更新时，这里处理位置信息
        double latitude = location.getLatitude();
        double longitude = location.getLongitude();
        
        // 验证位置信息的有效性
        if (latitude == 0.0 && longitude == 0.0) {
            Log.e("LocationError", "接收到无效的位置信息: " + latitude + "," + longitude);
            return;
        }

        SPUtil.put(SpKey.KEY_LATITUDE, String.valueOf(latitude), this);
        SPUtil.put(SpKey.KEY_LONGITUDE, String.valueOf(longitude), this);
        Log.e("LocationSuccess", "定位成功: " + latitude + "," + longitude);
    }


    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        // 处理状态变化
    }

    @Override
    public void onProviderEnabled(String provider) {
        // 处理提供者启用
    }

    @Override
    public void onProviderDisabled(String provider) {
        // 处理提供者禁用
    }

    public void Error(Throwable e) {
        String error = null;
        try {

            if (e instanceof SocketTimeoutException) {//请求超时
                error = "网络连接超时";
            } else if (e instanceof ConnectException) {//网络连接超时
                error = "网络连接超时";
            } else if (e instanceof SSLHandshakeException) {//安全证书异常
                error = "安全证书异常";
            } else if (e instanceof HttpException) {//请求的地址不存在
                int code = ((HttpException) e).code();
                if (code == 504) {
                    error = "网络异常，请检查您的网络状态";
                } else if (code == 502) {
                    error = e.getMessage();
                } else if (code == 404) {
                    error = "请求的地址不存在";
                } else {
                    error = "请求失败";
                }
            } else if (e instanceof UnknownHostException) {//域名解析失败
                error = "域名解析失败";
            } else
                error = e.getMessage();
            Toast.makeText(BaseApplication.getInstance(), error, Toast.LENGTH_SHORT).show();

        } catch (Exception e2) {
            e2.printStackTrace();
        }
    }


    public String getErrorMsg(Throwable e) {
        String error = null;
        try {

            if (e instanceof SocketTimeoutException) {//请求超时
                error = "网络连接超时";
            } else if (e instanceof ConnectException) {//网络连接超时
                error = "网络连接超时";
            } else if (e instanceof SSLHandshakeException) {//安全证书异常
                error = "安全证书异常";
            } else if (e instanceof HttpException) {//请求的地址不存在
                int code = ((HttpException) e).code();
                if (code == 504) {
                    error = "网络异常，请检查您的网络状态";
                } else if (code == 502) {
                    error = e.getMessage();
                } else if (code == 404) {
                    error = "请求的地址不存在";
                } else {
                    error = "请求失败";
                }
            } else if (e instanceof UnknownHostException) {//域名解析失败
                error = "域名解析失败";
            } else {
                error = e.getMessage();
            }
            return error;

        } catch (Exception e2) {
            e2.printStackTrace();
            return "";
        }
    }


    /***
     * 此方法用于改变背景的透明度，从而达到“变暗”的效果
     */
    public static void backgroundAlpha(Activity activity, float bgAlpha) {
        WindowManager.LayoutParams lp = activity.getWindow().getAttributes();
        lp.alpha = bgAlpha; //0.0-1.0
        activity.getWindow().setAttributes(lp);
        activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
    }

    /**
     * 检查 Activity 是否已销毁
     */
    private boolean isActivityDestroyed() {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
            return isDestroyed();
        }
        return isFinishing();
    }

    public void showToast(final String txt) {
        if (txt == null || txt.isEmpty()) {
            return;
        }
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                try {
                    // 检查 Activity 是否还存在且有效
                    if (isFinishing() || isActivityDestroyed()) {
                        return;
                    }
                    CustomToast.showToast(Utils.getApp().getApplicationContext(), txt);
                } catch (Exception e) {
                    // 如果显示 Toast 失败，使用系统 Toast 作为备用方案
                    try {
                        android.widget.Toast.makeText(Utils.getApp().getApplicationContext(), txt, android.widget.Toast.LENGTH_SHORT).show();
                    } catch (Exception e2) {
                        // 忽略所有异常，避免崩溃
                        e2.printStackTrace();
                    }
                }
            }
        });
    }

    /**
     * 如果检测到 IDA动态调试， 提示用户并关闭程序
     *
     * @param context
     */
    private static void alertAndExit(Activity context) {
        context.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                AlertDialog alertDialog = new AlertDialog.Builder(context).setTitle("温馨提示").setMessage("当前应用在调试状态，为保证应用安全，10秒后将自动退出应用，请先退出调试状态再打开APP，感谢理解。")
                        .setPositiveButton("确定（10s）", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                exitApp(context);
                            }
                        }).setCancelable(false).create();
                alertDialog.show();
                new CountDownTimer(10000, 1000) {  //11秒倒计时，每秒执行一次
                    public void onTick(long millisUntilFinished) {  //每秒执行一次进该方法
                        alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setText("确定（" + (millisUntilFinished / 1000 + 1) + "s）");
                    }

                    public void onFinish() {  //倒计时结束。
                        exitApp(context);
                    }
                }.start();
            }
        });
    }

    /**
     * 退出APP
     *
     * @param context
     */
    private static void exitApp(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            ActivityManager activityManager = (ActivityManager) context.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
            List<ActivityManager.AppTask> appTaskList = activityManager.getAppTasks();
            for (ActivityManager.AppTask appTask : appTaskList) {
                appTask.finishAndRemoveTask();
            }
        } else {
            android.os.Process.killProcess(android.os.Process.myPid());
        }

    }


    public boolean isNotificationPermissionGranted() {
        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            return notificationManager.areNotificationsEnabled();
        }
        return true; // 在较低版本中默认允许
    }

    public void showPermissionDialog() {
        new AlertDialog.Builder(this)
                .setTitle("启用通知")
                .setMessage("启用通知以便获取最新消息和更新。")
                .setPositiveButton("去设置", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                        Uri uri = Uri.fromParts("package", getPackageName(), null);
                        intent.setData(uri);
                        startActivity(intent);
                    }
                })
                .setNegativeButton("取消", null)
                .show();
    }
}
